﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text;

namespace HisPay.Payment
{
    public class HttpUtil
    {
        /**
	 * 通讯请求方法，传入支付请求参数放回结果，执行加密解密
	 * @param param
	 * @return
	 */
        public static Dictionary<String, Object> request(Dictionary<String, Object> param, String serviceName)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            Dictionary<String, Object> resultMap = null;
            String requestData = DESUtils.encode(param);
            Logger.debug(String.Format("[发送数据]-{0}", JsonConvert.SerializeObject(param)));
            try
            {
                String resultData = doRequest(requestData, serviceName);
                TimeSpan ts = sw.Elapsed;
                Logger.debug(String.Format("[网络耗时]-{0}ms", ts.TotalMilliseconds));
                resultMap = DESUtils.decode(resultData);
            }
            catch (ClientException e)
            {
                resultMap = e.toMap();
            }
            TimeSpan ts2 = sw.Elapsed;
            Logger.debug(String.Format("[接收数据]-{0}", JsonConvert.SerializeObject(resultMap)));
            Logger.debug(String.Format("[调用耗时]-{0}ms", ts2.TotalMilliseconds));
            return resultMap;
        }

        static String doRequest(String data, String serviceName)
        {
            HttpWebResponse response = null;
            Encoding encoding = Encoding.UTF8;
            String content = null;
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://"+Configs.SERVER_URL+"/"+serviceName);
                request.Timeout = Configs.CONN_TIMEOUT;
                request.ReadWriteTimeout = Configs.READ_TIMEOUT;
                request.ContentType = "text/plain;";
                request.Method = "POST";
                request.KeepAlive = true;
                request.ServicePoint.Expect100Continue = false;
                //是否使用 Nagle 不使用 提高效率 
                request.ServicePoint.UseNagleAlgorithm = false;
                //最大连接数 
                request.ServicePoint.ConnectionLimit = int.MaxValue;
                //数据是否缓冲 false 提高效率  
                request.AllowWriteStreamBuffering = false;

                byte[] buffer = encoding.GetBytes(data);
                request.ContentLength = buffer.Length;
            
                Stream ss = request.GetRequestStream();
                ss.Write(buffer, 0, buffer.Length);
                ss.Close();
                response = (HttpWebResponse)request.GetResponse();
            }catch(UriFormatException e)
            {
                Logger.debug(e);
                throw ClientException.NET_URL_ERROR;
            }
            catch (WebException we)
            {
                Console.WriteLine(we);
                response = (HttpWebResponse)we.Response;
            }
            //服务器连接失败
            if (response == null)
            {
                throw ClientException.NET_UNKNOW_ERROR;
            }
            if (response.StatusCode == HttpStatusCode.OK)
            {
                using (StreamReader reader = new StreamReader(response.GetResponseStream(), encoding))
                {
                    content = reader.ReadToEnd();
                }
            }
            else
            {
                Logger.debug(response.StatusCode.ToString());
                if (HttpStatusCode.NotFound == response.StatusCode)
                {
                    throw ClientException.SERVICE_NAME_ERROR;
                }
                throw ClientException.SERVER_ERROR;
            }
            if(content == null || "".Equals(content))
            {
                throw ClientException.SERVER_NO_BODY;
            }
            return content;
        }
    }
}
